package libra.forSentinel;

import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;

import java.util.HashMap;

import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse;

/**
 * Sentinel整合RestTemplate的自定义流控异常处理类
 * 启动的时候会检查 @SentinelRestTemplate 注解对应的限流或降级方法是否存在，如不存在会抛出异常！！！
 * 	限流、降级方法的参数列表、返回值需要与org.springframework.http.client.ClientHttpRequestInterceptor#interceptor()方法保持一致
 * 	其中参数多出了一个BlockException类型参数用于获取Sentinel捕获的异常。
 * @author libra
 */
public class BlockExHandler_RestTemplate {
	
    /**
     * Sentinel整合RestTemplate自定义限流处理方法
     * 注意：必须是static修饰，参数类型不能出错，参数多出了一个BlockException类型参数用于获取Sentinel捕获的异常
     */
    public static SentinelClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
		System.out.println("handleException: " + ex.getClass().getCanonicalName());
		return new SentinelClientHttpResponse(JSON.toJSONString( new HashMap<>() {{
			put("type", "block");
			put("ex", ex.getClass().getCanonicalName());
		}} ));
    }
    
    /**
     * Sentinel整合RestTemplate自定义降级处理方法
     * 注意：必须是static修饰，参数类型不能出错，参数多出了一个BlockException类型参数用于获取Sentinel捕获的异常
     */
    public static ClientHttpResponse handleFallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
    	System.out.println("handleFallback: " + ex.getClass().getCanonicalName());
		return new SentinelClientHttpResponse(JSON.toJSONString( new HashMap<>() {{
			put("type", "fallback");
			put("ex", ex.getClass().getCanonicalName());
		}} ));
    }

}
